
/* Author: Manfred Gschweidl */

#ifndef GLOBUSGRAMJOBSCALLBACK_H_
#define GLOBUSGRAMJOBSCALLBACK_H_

#include <cstdio>
#include <string>
#include <map>
#include "globus_gram_client.h"
#include "GlobusCallback.h"

using namespace std;
using namespace globus_common;

namespace globus_job {

class GlobusGramJobsCallback;
class GlobusGramJob;

//generic gram job callback manager, could handle more than one job
class GlobusGramJobsCallback {
	private:
		globus_mutex_t				JobsTableMutex;
		/* This is the identifier for the callback, returned by
		globus_gram_job_request */
		char*						callback_contact;
		//jobs map, key jobcontact
		map<string,GlobusGramJob*>	JobsTable;
		//functions
		void lock();
		void unLock();
	public:
		GlobusGramJobsCallback();
		~GlobusGramJobsCallback();
		//add job to manager
		void add(string,GlobusGramJob*);
		//remove job from manager
		void remove(char*);
		//get manager contact url
		char* getURL();
		//get job identified by jobcontact
		GlobusGramJob* getJob(char*);
};

class GlobusGramJob : public GlobusCallback {
	private:
		//job contact and identifier returned by
		//callback function from globus
		char*					jobcontact;
		//mutex
		globus_mutex_t			jobcontactmutex;
		//job failed?
		bool					failed;
		//pointer to callback manager
		GlobusGramJobsCallback*	callback;
		//flag for only waiting until got jobcontact
		bool					only_get_jobHandle;
	public:
		GlobusGramJob( GlobusGramJobsCallback* );
		GlobusGramJob( GlobusGramJobsCallback*, string );
		GlobusGramJob( string );
		~GlobusGramJob();
		//submit job (host, rsl)
		bool submit(string,string);
		//cancel job
		bool cancel();
		//set jobcontact - used by callback manager
		void setJobContact(const char*);
		//set job status failed
		void setFailed();
		//has job failed?
		bool hasFailed();
		//continue - possible reuse of object for other
		//job submissions
		void proceed();
		//get jobcontact string returned by globus
		string getJobContact();
		//only wait until jobcontact is set?
		bool onlyGetJobHandle();
		//set flag for only waiting until jobcontact has been set
		void setOnlyGetJobHandle(bool);
		//get status of the job from globus - blocking call
		//could be implemented non-blocking fro job polling
		int getJobStatus();
};

}

#endif /*GLOBUSGRAMJOBSCALLBACK_H_*/
